// *****************************************************************************
//
// Copyright (c) 2011. Hao Liu and Lin Gui, Ocean University of China and
// Carneggie Mellon University. This code may be used, distribute, or modified
// only for research purposes or under license from Ocean University of China or
// Carnegie Mellon University. This notice must be retained in all copies.
//
// *****************************************************************************

/*!
  \file         remotenodewindow.h
  \author       Lin Gui
  \version      1.0
  \date         2011/10/19
  \brief        Header file for remote waker's main class
*/


#ifndef REMOTENODEWINDOW_H
#define REMOTENODEWINDOW_H

#define DEBUG    //!< For debugging
#define CONFIGPATH "/home/guilin/Dev/argus-cmu/config/"    //!< Path of the config file
#define CONFILENAME "servermanager.ini"    //!< Name of the config file
#define COLUMNUM 5    //!< Column number of the node list table
//#define ROWNUM 20    //!< Row number of the node list table
#define ONLINETIP "Online"    //!< Online status tip
#define OFFLINETIP "Offline"    //!< Offline status tip
#define STARTINGTIP "Starting"    //!< Starting status tip
#define NOTWAKED "Not Waked"
#define TIMEOUT "Timeout"
//#define MAXTIME "00:05:00"    //!< Max time waiting for wakeonlan

#include <stdlib.h>
#include <stdio.h>

#include <QtGui/QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QTableWidget>
#include <QTextEdit>
#include <QPushButton>
#include <QTimer>
#include <QList>
#include <QSettings>
#include <QTime>

#include <QtGlobal>
#include <QDebug>

//! The mainwindow class of remote waker.
/*!
  This class implements the following tasks:
    drawing the interface of the remote waker,
    reading the config information (including the time intervals) and machine information,
    sending the wake on LAN and shutdown commands to the nodes computer,
    observing the wake-up status of the nodes computers.
*/

class RemoteNodeWindow : public QWidget
{
    Q_OBJECT

public:
    //! The constructor for class RemoteNodeWindow
    /*!
      Initialize all the pointers and variables in the constructor
    */
    RemoteNodeWindow(QWidget *parent = 0);
    ~RemoteNodeWindow();

    //! Define node wake status
    enum WAKESTATUS
    {
        ONLINE,     //!< Node is online or sucessfully waked
        OFFLINE,    //!< Node is offline or not waked successfully
        STARTING    //!< Node has been sent awaking signal but not online yet
    };

    //! A function used to lock or unlock the window
    /*!
      \param (bool) status: set the editable status of the widgets in window to status
    */
    void enableWindow(bool status);

public slots:
    // The slots that respons to the timers
    //! A private slot, responding to the timeyout() signal emitted by wakeInterval
    void onWakeInterval();

    //! A private slot, responding to the timeyout() signal emitted by checkInterval
    void onCheckInterval();

    // The functions that respons to the buttons
    //! A private slot, responding to the click on 'Wake on LAN' button
    void onBtnWakeOnLan();

    //! A private slot, responding to the click on 'shutdown' button
    void onBtnShutdown();

    //! A private slot, responding to the click on 'Refresh' button
    /*!
    */
    void onBtnRefresh();

    //! A private slot, responding to the click on 'Select All' button
    /*!
      Set the status of all the node machines listed in the tablewidget to Checked
    */
    void onBtnSelectAll();

    //! A private slot, responding to the click on 'Unelect All' button
    /*!
      Set the status of all the node machines listed in the tablewidget to Unchecked
    */
    void onBtnUnselectAll();

#ifdef DEBUG
    //! A test function, responding to the click on 'test enable status' button
    /*!
      Enable and disable the editable status of window, to check the enabelWindow() function
    */
    void ontestEnableButton();
#endif

private:
    // Variables:
    // window layouts
    QVBoxLayout *mainVLayout;           //!< Holding all the widges in the window
    QHBoxLayout *nodesHLayout;          //!< Holding the upper area of the window, except the textarea
    QVBoxLayout *buttonVLayout;         //!< Holding the command buttons on the right
    QVBoxLayout *tableVLayout;          //!< Holding the table widget and the select/unselect buttons
    QHBoxLayout *checkHLayout;          //!< Holding the select/unselect buttons

    // window widgets
    // table widget
    QTableWidget *nodeList;             //!< Information table of the node machines
    // output text area
    QTextEdit *outputText;              //!< Display the output messages
    // buttons
    QPushButton *btnWakeOnLan;          //!< Start waking all the selected node machines
    QPushButton *btnShutdown;           //!< Shutdown all the selected node machines
    QPushButton *btnRefresh;            //!< Get the newest status of all nodes
    QPushButton *btnSelectAll;          //!< Select all nodes listed in the table
    QPushButton *btnUnselectAll;        //!< Unelect all nodes listed in the table

    // ini config file reader
    QSettings *wakeConfig;              //!< Pointer to the instance that save the configure information

    // Timers
    QTimer wakeInterval;                //!< Trigger the relevant functions to send 'wake on LAN' signal
    QTimer checkInterval;               //!< Trigger the relevant functions to check the nodes' status
    // Interval seconds of the timers
    int wakeSeconds;                    //!< Time interval between two 'wake on LAN' signals
    int checkSeconds;                   //!< Time interval between checking status when awaking all the nodes
    int checkCount;                     //!< Count the time of checking status

    // List of selected nodes
    QList<int> *selectedNodes;        //!< Pointer to the vector that recording the index of selected nodes
    QTime globalTime;                 //!< The global clock
    int wakeTimeout;                  //!< The max waking time for wakeonlan, the unit is second

    // Functions:
    //! Initialization function
    /*!
      Initialize the layout of the interface.
    */
    void initWindow();

    //! Reading config function
    /*!
      Read the configure infor and nodes infor from files, and load them into tablewidget
    */
    void readConfig();

    //! Status checking function
    /*!
      Check the waking status of a node machine
      \param (int) nodeNum: the number of one node machine
    */
    bool checkWakeStatus(int nodeNum);

    //! Set the status of a node
    /*!
      \param (int) nodeNum: the number of one node machine
      \param (QString) status: the target status to change
    */
    void setWakeStatus(int nodeNum, QString status);
};

#endif // REMOTENODEWINDOW_H
